package me.utils.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import me.utils.Static;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author FengDuqing
 * @see http://git.oschina.net/loolly/common-tools/blob/master/src/main/java/com/baijob/commonTools/DateUtil.java
 * @see http://git.oschina.net/yuancihang/yuan-common/blob/master/src/com/yuan/common/util/DateUtil.java
 * 
 * @version 1.0
 */
public class DateUtil {
	private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
	/**---------------------------------------------------------------------*
	 * TODO 获取时间通用类
	 **---------------------------------------------------------------------*/
	/**
	 * 当前时间，格式 yyyy-MM-dd HH:mm:ss
	 * @return 当前时间的标准形式字符串
	 */
	public static String getNow() {
		return formatDateTime(new Date());
	}
	/**
	 * 当前日期，格式 yyyy-MM-dd
	 * @return 当前日期的标准形式字符串
	 */
	public static String getToday() {
		return formatDate(new Date());
	}
	/**
	 * 获取当前年份
	 * @return 当前年份
	 */
	public static int getCurrentYear(){
		Calendar c = Calendar.getInstance();
		return c.get(Calendar.YEAR);
	}
	/**
	 * 获取当前月份
	 * @return 当前月份
	 */
	public static int getCurrentMonth(){
		Calendar c = Calendar.getInstance();
		return c.get(Calendar.MONTH) + 1;
	}
	/**
	 * 获取当前年份的生肖
	 * @return 当前年份的生肖
	 */
	public static String getZodica(){
		int pos = getCurrentYear() % 12;
		return Static.zodiacList[pos];
	}
	/**
	 * 获取指定年份的生肖
	 * @param time 年份
	 * @return 指定年份的生肖
	 */
	public static String getZodica(Calendar time){
		int pos = time.get(Calendar.YEAR) % 12;
		return Static.zodiacList[pos];
	}
	/**
	 * 获取指定日历的星座
	 * @param time 指定日历
	 * @return 指定日历的星座
	 */
	public static String getConstellation(Calendar time){
		 int month = time.get(Calendar.MONTH);   
	        int day = time.get(Calendar.DAY_OF_MONTH);   
	        if (day < Static.constellationEdgeDay[month]) {   
	            month = month - 1;   
	        }   
	        if (month >= 0) {   
	            return Static.constellationList[month];   
	        }   
	        return Static.constellationList[11];  
	}
	/**---------------------------------------------------------------------*
	 * TODO 格式化时间通用类
	 **---------------------------------------------------------------------*/
	 
	/**
	 * 根据特定格式格式化日期
	 * @param date 被格式化的日期
	 * @param format 格式
	 * @return 格式化后的字符串
	 */
	public static String format(Date date, String format){
		return new SimpleDateFormat(format).format(date);
	}
	/**
	 * 格式 yyyy-MM-dd HH:mm:ss
	 * @param date 被格式化的日期
	 * @return 格式化后的日期
	 */
	public static String formatDateTime(Date date) {
		return Static.NORM_DATETIME_FORMAT.format(date);
	}
	/**
	 * 格式化为Http的标准日期格式(EEE, dd MMM yyyy HH:mm:ss z)
	 * @param date 被格式化的日期
	 * @return HTTP标准形式日期字符串
	 */
	public static String formatHttpDate(Date date) {
		return Static.HTTP_DATETIME_FORMAT.format(date);
	}
	
	/**
	 * 格式话为 yyyy-MM-dd
	 * @param date 被格式化的日期
	 * @return 格式化后的字符串
	 */
	public static String formatDate(Date date) {
		return Static.NORM_DATE_FORMAT.format(date);
	}
	/**---------------------------------------------------------------------*
	 * TODO 转换时间
	 **---------------------------------------------------------------------*/
	/**
	 * 将特定格式的日期转换为Date对象
	 * @param dateString 特定格式的日期
	 * @param format 格式，例如yyyy-MM-dd
	 * @return 日期对象
	 */
	public static Date parse(String dateString, String format){
		try {
			return (new SimpleDateFormat(format)).parse(dateString);
		} catch (ParseException e) {
			logger.error("Parse " + dateString + " with format " + format + " error!", e);
		}
		return null;
	}
	
	/**
	 * 格式yyyy-MM-dd HH:mm:ss
	 * @param dateString 标准形式的时间字符串
	 * @return 日期对象
	 */
	public static Date parseDateTime(String dateString){
		try {
			return Static.NORM_DATETIME_FORMAT.parse(dateString);
		} catch (ParseException e) {
			logger.error("Parse " + dateString + " with format " + Static.NORM_DATETIME_FORMAT.toPattern() + " error!", e);
		}
		return null;
	}
	
	/**
	 * 格式yyyy-MM-dd
	 * @param dateString 标准形式的日期字符串
	 * @return 日期对象
	 */
	public static Date parseDate(String dateString){
		try {
			return Static.NORM_DATE_FORMAT.parse(dateString);
		} catch (ParseException e) {
			logger.error("Parse " + dateString + " with format " + Static.NORM_DATE_FORMAT.toPattern() + " error!", e);
		}
		return null;
	}
	/**---------------------------------------------------------------------*
	 * TODO 偏移时间
	 **---------------------------------------------------------------------*/
	/**
	 * 获取指定日期偏移指定时间后的时间
	 * @param date 基准日期
	 * @param calendarField 偏移的粒度大小（小时、天、月等）使用Calendar中的常数
	 * @param offsize 偏移量，正数为向后偏移，负数为向前偏移
	 * @return 偏移后的日期
	 */
	public static Date getDateOffsize(Date date, int calendarField, int offsize){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendarField, offsize);
		return calendar.getTime();
	}
	
	/**
	 * 判断两个日期相差的时长<br/>
	 * 返回 minuend - subtrahend 的差
	 * @param date1 减数日期
	 * @param date2 被减数日期
	 * @return 日期差
	 */
	public static long getDateDiff(Date date1, Date date2){ 
	  long diff = date2.getTime() - date1.getTime();
	  return diff; 
	}
	/**
	 *  计算两个日期相差多少天
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long getDateDiffDay(Date date1, Date date2){
		long diff = getDateDiff(date1, date2);
		return diff/Static.DAY_MS; 
	}
	/**
	 *  计算两个日期相差多少小时
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long getDateDiffHour(Date date1, Date date2){
		long diff = getDateDiff(date1, date2);
		return diff/Static.HOUR_MS; 
	}
	/**
	 *  计算两个日期相差多少分钟
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long getDateDiffMinute(Date date1, Date date2){
		long diff = getDateDiff(date1, date2);
		return diff/Static.MINUTE_MS; 
	}
	/**
	 *  计算两个日期相差多少分钟
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long getDateDiffSecond(Date date1, Date date2){
		long diff = getDateDiff(date1, date2);
		return diff/Static.SECOND_MS; 
	}
	/**
	 * 解析一个时间间隔
	 * @param quantum long 用毫秒数表示的时间段
	 * @return 格式化后的时间间隔
	 */
	public static String parseTimeQuantum(long quantum){
		long day = 0L;
		long hour = 0;
		long minute = 0;
		long second = 0;
		long millisecond = 0;
		long tmp = 0L;
		
		millisecond = quantum;
		if(quantum < 1000){
			return millisecond + "毫秒";
		}
		
		millisecond = quantum%1000L;
		second = quantum/1000L;
		if(second < 60){
			return second + "秒" + millisecond + "毫秒";
		}
		
		tmp = second;
		second = tmp%60L;
		minute = tmp/60L;
		if(minute < 60){
			return minute + "分钟" + second + "秒" + millisecond + "毫秒";
		}
		
		tmp = minute;
		minute = tmp % 60L;
		hour = tmp / 60L;
		if(hour < 24){
			return hour + "小时" + minute + "分钟" + second + "秒" + millisecond + "毫秒";
		}
		
		tmp = hour;
		hour = tmp % 24L;
		day = tmp /24L;
		
		return day + "天" + hour + "小时" + minute + "分钟" + second + "秒" + millisecond + "毫秒";
	}
	/**---------------------------------------------------------------------*
	 * TODO 时区处理
	 **---------------------------------------------------------------------*/
	/**
	 * 将时间从一个时区转换到另一个时区
	 * @param time		时间
	 * @param timeZone1	时区1
	 * @param timeZone2	时区2
	 * @return 转换后的时区
	 */
	public static long convertTimeZone(long time, TimeZone timeZone1, TimeZone timeZone2){
		int diffTime = timeZone2.getRawOffset() - timeZone1.getRawOffset();
		return time + diffTime;
	}
	/**
	 * 计算时区, -12 ~ 12
	 * @param timeZone
	 * @return	时区值
	 */
	public static int getTimeZoneValue(TimeZone timeZone){
		return timeZone.getRawOffset() / (3600 * 1000);
	}
	/**
	 * 获取当前时区
	 * @return	当前时区
	 */
	public static int getCurrentTimeZoneValue(){
		return getTimeZoneValue(TimeZone.getDefault());
	}
}
